/**
 * Copyright © 2013 Creativor Studio.
 * About license information, please see LICENSE.txt.
 */
package org.creativor.rayson.client.proxy;

import java.lang.reflect.Proxy;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;

import org.creativor.rayson.api.Protocol;

/**
 * The role used to manage RPC proxy.
 * 
 * @author creativor
 */
public final class ProxyManager {
	private final Map<ProxyKey, Protocol> cache;

	/**
	 */
	public ProxyManager() {
		cache = new HashMap<>();
	}

	/**
	 * @param key
	 * @return
	 */
	private Protocol createNewProxy(final ProxyKey key) {
		final Protocol proxy = ((Protocol) Proxy
				.newProxyInstance(
						key.getLoader(),
						new Class[] { key.getProtocol() },
						new RpcInvocationHandler(key.getServerAddr(), key
								.getProtocol())));
		cache.put(key, proxy);
		return proxy;
	}

	/**
	 * Get RPC proxy of given protocol and server address.
	 * 
	 * @param serverAddr
	 * @param protocol
	 * @return RPC proxy.
	 */
	public synchronized <T extends Protocol> T getProxy(
			final InetSocketAddress serverAddr, final Class<T> protocol) {
		final ProxyKey key = new ProxyKey(protocol.getClassLoader(),
				serverAddr, protocol);
		Protocol proxy = cache.get(key);
		if (proxy == null) {
			proxy = createNewProxy(key);
		}
		return (T) proxy;
	}

	/**
	 * Do initialize this manager.
	 */
	public void initialize() {
		// TODO: Implements me.
	}
}